<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="自定义时间段" label-width="100px">
        <el-date-picker
          v-model="dateRange"
          size="small"
          style="width: 240px"
          value-format="yyyy-MM-dd"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        ></el-date-picker>
      </el-form-item>

      <el-form-item label="工号/学号" label-width="80px" prop="studentId">
        <el-input
          v-model="queryParams.studentId"
          placeholder="请输入工号/学号"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="手机号" prop="phonenumber">
        <el-input
          v-model="queryParams.phonenumber"
          placeholder="请输入手机号"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="姓名" prop="nickName">
        <el-input
          v-model="queryParams.nickName"
          placeholder="请输入姓名"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>

      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleImport(1)"
          v-hasPermi="['account:manage:batchAdd']"
          >批量新增</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          @click="handleImport(0)"
          v-hasPermi="['account:manage:batchRemove']"
        >
          批量删除
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-download"
          size="mini"
          @click="handleExport"
          v-hasPermi="['account:manage:export']"
          >导出</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['account:manage:add']"
          >新增</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['account:manage:edit']"
        >
          修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['account:manage:remove']"
        >
          删除
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="el-icon-key"
          size="mini"
          :disabled="single"
          @click="handleResetPwd"
          v-hasPermi="['account:manage:reset']"
        >
          修改密码
        </el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="tableList" style="width: 100%" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="工号/学号" align="center" prop="studentId" />
      <el-table-column label="创建时间" align="center" prop="createTime" width="150px" />
      <el-table-column label="姓名" align="center" prop="nickName" />
      <el-table-column label="电话" align="center" prop="phonenumber" width="120px" />
      <el-table-column label="身份证" align="center" prop="card" width="170px" />
      <el-table-column label="角色" align="center" prop="sysRoleList" :formatter="formatRole" />
      <el-table-column label="岗位" align="center" prop="sysPostList" :formatter="formatPost" />
      <el-table-column label="用户组" align="center" prop="groupList" :formatter="formatGroup" />
      <el-table-column label="部门" align="center" prop="dept" :formatter="formatDept" />
      <el-table-column label="状态" align="center" prop="status">
        <template slot-scope="scope">
          <el-switch
            v-model="scope.row.status"
            active-value="0"
            inactive-value="1"
            @change="handleStatusChange(scope.row)"
          ></el-switch>
        </template>
      </el-table-column>
      <el-table-column
        v-for="meta in metaList"
        :label="meta.metadataName"
        align="center"
        prop="metadataContent"
        :formatter="formatMeta(meta.metadataId)"
      />
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="150px">
        <div class="add-form">
          <div class="add-form-item">
            <el-form-item label="用户名" prop="userName">
              <el-input v-model="form.userName" placeholder="请输入用户名" />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="工号/学工号" prop="studentId">
              <el-input v-model="form.studentId" placeholder="请输入工号/学工号" />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="姓名" prop="nickName">
              <el-input v-model="form.nickName" placeholder="请输入姓名" />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="手机号码" prop="phonenumber">
              <el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="身份证" prop="card">
              <el-input v-model="form.card" placeholder="请输入身份证" maxlength="50" />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="性别">
              <el-select style="width: 100%" v-model="form.sex" placeholder="请选择">
                <el-option
                  v-for="dict in sexOptions"
                  :key="dict.dictValue"
                  :label="dict.dictLabel"
                  :value="dict.dictValue"
                ></el-option>
              </el-select>
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="角色" props="roleIds">
              <el-select style="width: 100%" v-model="form.roleIds" multiple placeholder="请选择">
                <el-option
                  v-for="item in roleOptions"
                  :key="item.roleId"
                  :label="item.roleName"
                  :value="item.roleId"
                  :disabled="item.status == 1"
                ></el-option>
              </el-select>
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="状态" props="status">
              <el-radio-group v-model="form.status">
                <el-radio v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue">
                  {{ dict.dictLabel }}
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="用户组" props="groupIds">
              <treeselect
                v-model="form.groupIds"
                :multiple="true"
                :options="groupOptions"
                :show-count="true"
                :flat="true"
                placeholder="请选择用户组"
              />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="部门" prop="deptId">
              <treeselect
                v-model="form.deptId"
                :options="deptOptions"
                :show-count="true"
                placeholder="请选择归属部门"
              />
            </el-form-item>
          </div>
          <div class="add-form-item">
            <el-form-item label="岗位" prop="postIds">
              <el-select style="width: 100%" v-model="form.postIds" multiple placeholder="请选择">
                <el-option
                  v-for="item in postOptions"
                  :key="item.postId"
                  :label="item.postName"
                  :value="item.postId"
                  :disabled="item.status == 1"
                ></el-option>
              </el-select>
            </el-form-item>
          </div>
          <div class="add-form-item" v-for="(meta, index) in metaList" :key="'metaItem' + index">
            <el-form-item
              v-if="meta.htmlType === 'input'"
              :label="meta.metadataName"
              :key="meta.metadataId"
              :rules="{ required: meta.isRequired === '1', message: meta.metadataPrompt, trigger: 'blur' }"
              :prop="'metadataContentVoList.' + index + '.contentComment'"
            >
              <el-input
                v-model="metadataContentVoList[index].contentComment"
                :placeholder="meta.metadataPrompt"
                @input="$forceUpdate()"
              />
            </el-form-item>
            <el-form-item
              :rules="{ required: meta.isRequired === '1', message: meta.metadataPrompt, trigger: 'blur' }"
              v-else-if="meta.htmlType === 'textarea'"
              :label="meta.metadataName"
              :key="meta.metadataId"
              :prop="'metadataContentVoList.' + index + '.contentComment'"
            >
              <el-input
                type="textarea"
                v-model="metadataContentVoList[index].contentComment"
                :placeholder="meta.metadataPrompt"
                @input="$forceUpdate()"
              />
            </el-form-item>
            <el-form-item
              :rules="{ required: meta.isRequired === '1', message: meta.metadataPrompt, trigger: 'blur' }"
              v-else-if="meta.htmlType === 'datetime'"
              :label="meta.metadataName"
              :key="meta.metadataId"
              :prop="'metadataContentVoList.' + index + '.contentComment'"
            >
              <el-date-picker
                v-model="metadataContentVoList[index].contentComment"
                type="date"
                value-format="yyyy-MM-dd"
                :placeholder="meta.metadataPrompt"
              ></el-date-picker>
            </el-form-item>
            <el-form-item
              :rules="{ required: meta.isRequired === '1', message: meta.metadataPrompt, trigger: 'blur' }"
              v-else-if="meta.htmlType === 'select'"
              :label="meta.metadataName"
              :key="meta.metadataId"
              :prop="'metadataContentVoList.' + index + '.contentComment'"
            >
              <el-select
                style="width: 100%"
                v-model="metadataContentVoList[index].contentComment"
                :placeholder="meta.metadataPrompt"
              >
                <el-option v-for="item in meta.selectComment" :key="item" :label="item" :value="item"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              :rules="{ required: meta.isRequired === '1', message: meta.metadataPrompt, trigger: 'blur' }"
              v-else-if="meta.htmlType === 'file'"
              :label="meta.metadataName"
              :key="meta.metadataId"
              :prop="'metadataContentVoList.' + index + '.contentComment'"
            >
              <el-upload
                class="upload-demo"
                :headers="metaUpload.headers"
                :on-success="handleMetaUploadSuccess(index)"
                :on-remove="handleMetaUploadRemove(index)"
                :file-list="metadataContentVoList[index].contentComment"
                :action="metaUpload.url"
              >
                <el-button size="small" type="primary">点击上传</el-button>
              </el-upload>
            </el-form-item>
          </div>
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 批量新增/删除 对话框 -->
    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
      <el-upload
        ref="upload"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url + '?updateSupport=' + upload.updateSupport"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          <el-checkbox v-model="upload.updateSupport" />
          是否更新已经存在的用户数据
        </div>
        <div class="el-upload__tip" slot="tip">
          <el-link icon="el-icon-download" type="info" style="font-size: 14px" @click="importTemplate"
            >下载模板</el-link
          >
        </div>
        <div class="el-upload__tip" style="color: red" slot="tip">提示：仅允许导入“xls”或“xlsx”格式文件！</div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import {
    listAccount,
    getAccount,
    delAccount,
    addAccount,
    updateAccount,
    exportAccount,
    changeAccountStatus,
    importTemplate,
    resetAccountPwd
  } from './service'
  import { getToken } from '@/utils/auth'
  import { treeselect } from '@/api/system/dept'
  import Treeselect from '@riophae/vue-treeselect'
  import '@riophae/vue-treeselect/dist/vue-treeselect.css'
  export default {
    name: 'AccountManage',
    components: { Treeselect },
    data() {
      return {
        // 遮罩层
        loading: false,
        typeOptions: [],
        // 状态数据字典
        statusOptions: [],
        // 部门树选项
        deptOptions: undefined,
        // 性别状态字典
        sexOptions: [],
        postOptions: [],
        roleOptions: [],
        groupOptions: [],
        // 日期范围
        dateRange: [],
        // 选中数组
        ids: [],
        // 选中行
        selectedRows: [],
        // 非单个禁用
        single: true,
        // 非多个禁用
        multiple: true,
        // 显示搜索条件
        showSearch: true,
        // 总条数
        total: 0,
        // 表格数据
        tableList: [],
        // 元数据 数组
        metaList: [],
        metaInitFlag: false,
        // 弹出层标题
        title: '',
        // 是否显示弹出层
        open: false,
        // 查询参数
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          params: {}
        },
        // 表单参数
        form: {
          status: '0'
        },
        metadataContentVoList: [],
        // 表单校验
        rules: {
          userName: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
          studentId: [{ required: true, message: '工号/学工号不能为空', trigger: 'blur' }],
          nickName: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
          phonenumber: [
            {
              required: true,
              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
              message: '请输入正确的手机号码',
              trigger: 'blur'
            }
          ],
          card: [
            {
              required: true,
              pattern: /^((\d{17}[0-9xX])|(\d{15}))$/,
              message: '请输入正确的身份证号码',
              trigger: 'blur'
            }
          ]
        },
        metaRules: {},
        // 批量新增/删除 导入参数
        upload: {
          // 是否显示弹出层（导入）
          open: false,
          // 弹出层标题（导入）
          title: '',
          // 是否禁用上传
          isUploading: false,
          // 设置上传的请求头部
          headers: { Authorization: 'Bearer ' + getToken() },
          // 上传的地址
          url: '',
          updateSupport: false
        },
        // 新增/删除 上传控件
        metaUpload: {
          // 设置上传的请求头部
          headers: { Authorization: 'Bearer ' + getToken() },
          // 上传的地址
          url: process.env.VUE_APP_BASE_API + '/common/pics'
        }
      }
    },
    watch: {
      // 根据名称筛选部门树
      deptName(val) {
        this.$refs.tree.filter(val)
      }
    },
    created() {
      this.getList()
    },
    mounted() {
      this.requestTreeSelect()
      this.getDicts('sys_user_sex').then(response => {
        this.sexOptions = response.data
      })
      this.getDicts('sys_normal_disable').then(response => {
        if (response.code === 200) {
          this.statusOptions = response.data
        }
      })
      getAccount().then(res => {
        if (res.code === 200) {
          this.postOptions = res.posts
          this.roleOptions = res.roles
          this.groupOptions = res.groups
        }
      })
    },
    methods: {
      formatRole(row, column, cellValue, index) {
        return Array.isArray(cellValue) ? cellValue.map(item => item.roleName).join('，') : '-'
      },
      formatGroup(row, column, cellValue, index) {
        return Array.isArray(cellValue) ? cellValue.map(item => item.userGroupName).join('，') : '-'
      },
      formatDept(row, column, cellValue, index) {
        return cellValue ? cellValue.deptName : '-'
      },
      formatPost(row, column, cellValue, index) {
        return Array.isArray(cellValue) ? cellValue.map(item => item.postName).join('，') : '-'
      },
      formatMeta(key) {
        return function(row, column, cellValue, index) {
          return cellValue[key] || ''
        }
      },
      initMetaForm(list) {
        this.metadataContentVoList = list.map(item => {
          const newItem = {
            metadataId: item.metadataId,
            contentComment: item.htmlType === 'file' ? [] : ''
          }
          return newItem
        })
      },
      /** 查询列表 */
      getList() {
        this.loading = true
        listAccount(this.queryParams)
          .then(res => {
            if (res.code === 200) {
              this.tableList = res.rows
              if (!this.metaInitFlag) {
                const newList = res.especially || []
                this.initMetaForm(newList)
                this.metaInitFlag = true
                this.metaList = newList.map(item => {
                  item.selectComment = (item.selectComment || '').split(',')
                  return item
                })
              }
              this.total = res.total
            }
          })
          .finally(() => {
            this.loading = false
          })
      },
      /** 查询部门下拉树结构 */
      requestTreeSelect() {
        treeselect().then(response => {
          this.deptOptions = response.data
        })
      },
      // 取消按钮
      cancel() {
        this.open = false
        this.reset()
      },
      // 表单重置
      reset() {
        this.initMetaForm(this.metaList)
        this.form = {
          status: '0',
          metadataContentVoList: this.metadataContentVoList
        }
        this.resetForm('form')
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.queryParams.pageNum = 1
        if (this.dateRange && this.dateRange[0]) {
          this.queryParams.params.beginTime = this.dateRange[0]
          this.queryParams.params.endTime = this.dateRange[1]
        } else {
          this.queryParams.params = {}
        }
        this.getList()
      },
      /** 重置按钮操作 */
      resetQuery() {
        this.resetForm('queryForm')
        this.queryParams.params = {}
        this.dateRange = []
        this.handleQuery()
      },
      // 用户状态修改
      handleStatusChange(row) {
        let text = row.status === '0' ? '启用' : '停用'
        this.$confirm('确认要' + text + '“' + row.userName + '”用户吗?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(function() {
            return changeAccountStatus(row.studentId, row.status)
          })
          .then(() => {
            this.msgSuccess(text + '成功')
          })
          .catch(function() {
            row.status = row.status === '0' ? '1' : '0'
          })
      },
      // 多选框选中数据
      handleSelectionChange(selection) {
        this.ids = selection.map(item => item.studentId)
        this.selectedRows = selection
        this.single = selection.length !== 1
        this.multiple = !selection.length
      },
      /** 新增按钮操作 */
      handleAdd() {
        this.reset()
        this.open = true
        this.title = '新增'
      },
      /** 修改按钮操作 */
      handleUpdate(row) {
        this.reset()
        const userId = row.studentId || this.ids
        getAccount(userId).then(response => {
          this.form = {
            ...response.data,
            metadataContentVoList: this.metadataContentVoList
          }
          this.form.postIds = response.postIds
          this.form.roleIds = response.roleIds
          this.form.groupIds = response.groupIds
          const metaObj = response.metadataContent || {}
          const newMetaList = this.metadataContentVoList
            .map(item => ({
              ...item,
              contentComment: metaObj[item.metadataId]
            }))
            .map((item, index) => {
              if (this.metaList[index].htmlType === 'file') {
                item.contentComment = item.contentComment
                  ? item.contentComment.split(',').map(item => ({
                      name: item,
                      url: item,
                      response: { data: { filePath: item } }
                    }))
                  : []
              }
              return item
            })
          newMetaList.forEach((item, index) => {
            this.$set(this.metadataContentVoList, index, this.generateProptyObj(item))
          })

          this.open = true
          this.title = '修改'
        })
      },
      generateProptyObj(obj) {
        const gObj = {}
        for (let key in obj) {
          this.$set(gObj, key, obj[key] || '')
        }
        return gObj
      },
      /** 导入按钮操作 */
      handleImport(isAdd) {
        this.upload.url = isAdd
          ? process.env.VUE_APP_BASE_API + '/system/user/importData'
          : process.env.VUE_APP_BASE_API + '/system/user/importDeleteData'
        this.upload.title = isAdd ? '批量新增' : '批量删除'
        this.upload.open = true
      },
      // 文件上传中处理
      handleFileUploadProgress(event, file, fileList) {
        this.upload.isUploading = true
      },
      // 文件上传成功处理
      handleFileSuccess(response, file, fileList) {
        this.upload.open = false
        this.upload.isUploading = false
        this.$refs.upload.clearFiles()
        this.$alert(response.msg, '导入结果', { dangerouslyUseHTMLString: true })
        this.getList()
      },

      // 新增 文件上传成功处理
      handleMetaUploadSuccess(index) {
        const that = this
        return function(response, file, fileList) {
          that.metadataContentVoList[index].contentComment = fileList
        }
      },
      // 新增 文件删除成功处理
      handleMetaUploadRemove(index) {
        const that = this
        return function(file, fileList) {
          that.metadataContentVoList[index].contentComment = fileList
        }
      },
      /** 下载模板操作 */
      importTemplate() {
        importTemplate().then(response => {
          this.download(response.msg)
        })
      },
      /** 重置密码按钮操作 */
      handleResetPwd() {
        const row = this.selectedRows[0]
        this.$prompt('请输入"' + row.userName + '"的新密码', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消'
        })
          .then(({ value }) => {
            resetAccountPwd(row.studentId, value).then(response => {
              this.msgSuccess('修改成功，新密码是：' + value)
            })
          })
          .catch(() => {})
      },
      submitFileForm() {
        this.$refs.upload.submit()
      },
      /** 提交按钮 */
      submitForm() {
        this.form.metadataContentVoList = this.metadataContentVoList.map(item => ({
          ...item,
          contentComment: Array.isArray(item.contentComment)
            ? item.contentComment.map(item => item.response.data.filePath).join(',')
            : item.contentComment
        }))
        this.$refs['form'].validate(valid => {
          if (valid) {
            if (this.form.studentId != null) {
              updateAccount(this.form).then(response => {
                this.msgSuccess('修改成功')
                this.open = false
                this.getList()
              })
            } else {
              addAccount(this.form).then(response => {
                this.msgSuccess('新增成功')
                this.open = false
                this.getList()
              })
            }
          }
        })
      },

      /** 删除按钮操作 */
      handleDelete() {
        const userIds = this.ids
        this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(function() {
            return delAccount(userIds)
          })
          .then(() => {
            this.getList()
            this.msgSuccess('删除成功')
          })
      },
      /** 导出按钮操作 */
      handleExport() {
        const queryParams = this.queryParams
        this.$confirm('是否确认导出所有用户数据项?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(function() {
            return exportAccount(queryParams)
          })
          .then(response => {
            this.download(response.msg)
          })
      }
    }
  }
</script>
<style lang="scss" type="text/scss">
  .add-form {
    display: flex;
    flex-wrap: wrap;
    padding: 0 4% 0 2%;
    box-sizing: border-box;
    justify-content: space-between;
    .add-form-item {
      width: 48%;
    }
  }
  .el-button--primary.is-plain:hover{
    color: #fff!important;
  }
</style>
